import React from 'react';
import { Balloon, Button } from '@teamix/ui';
import Pagination from 'components/commonPagination';
import { YunxiaoTable, Title } from '@alife/devops-ui';
import ListLoading from 'atComponents/ListLoading';
import exceed from 'utils/apimap';
import utils from 'utils';
import groupBy from 'lodash.groupby';
import { PROJECT_ADMIN_ROLES, PROJECT_DEVELOPER_ROLES, PROJECT_VIEW_ROLES } from 'utils/constants';
import ListEmpty from 'atComponents/ListEmpty';
import RuleModal from '../newRuleModal';
import Filter from './filter';
import intl from '../../../../../../../../../../../locale';

const { id: org_id, organization_id } = window.FORCE.organization;
const { Tooltip } = Balloon;
const ACTION_TYPES = {
  REPO_OPERATION: intl.get({
    id: 'code-assets.sensitiveBehaviorMonitor.recordTable.DatabaseOperations',
    defaultMessage: '库操作',
  }),
  AUTHORITY_CHANGE: intl.get({
    id: 'code-assets.sensitiveBehaviorMonitor.recordTable.PermissionChange',
    defaultMessage: '权限变更',
  }),
};

const BEHAVIORS = {
  FREQUENT_PULL: intl.get({
    id: 'code-assets.sensitiveBehaviorMonitor.recordTable.LargePullCodeBase',
    defaultMessage: '大量拉取代码库',
  }),
  SENSITIVE_DEL_REPO: intl.get({
    id: 'code-assets.sensitiveBehaviorMonitor.recordTable.AbnormalDatabaseDeletion',
    defaultMessage: '异常删库',
  }),
  SENSITIVE_MOD_MEMBER: intl.get({
    id: 'code-assets.sensitiveBehaviorMonitor.recordTable.ModifyDatabaseMembers',
    defaultMessage: '修改库成员',
  }),
  SENSITIVE_ORG_ADD_ADMIN: intl.get({
    id: 'code-assets.sensitiveBehaviorMonitor.recordTable.AddAnEnterpriseAdministrator',
    defaultMessage: '添加企业管理员',
  }),
  SENSITIVE_ORG_ADD_OWNER: intl.get({
    id: 'code-assets.sensitiveBehaviorMonitor.recordTable.AddAnEnterpriseOwner',
    defaultMessage: '添加企业拥有者',
  }),
  SENSITIVE_ORG_DEL_ADMIN: intl.get({
    id: 'code-assets.sensitiveBehaviorMonitor.recordTable.DeleteAnEnterpriseAdministrator',
    defaultMessage: '删除企业管理员',
  }),
  SENSITIVE_ORG_DEL_OWNER: intl.get({
    id: 'code-assets.sensitiveBehaviorMonitor.recordTable.DeleteAnEnterpriseOwner',
    defaultMessage: '删除企业拥有者',
  }),
};

export default class MonitorTable extends React.Component {
  state = {
    tableData: [],
    isLoading: true,
    total: 0,
    page: 1,
    openRowKeys: [],
    isModalOpen: false,
    tableParams: {},
    modalData: {},
  };

  componentDidMount() {
    this.getSensitiveBehaviorList(1);
  }

  updateRecordParams = (tableParams) => {
    this.setState(
      {
        tableParams,
      },

      () => {
        this.getSensitiveBehaviorList(1);
      },
    );
  };

  // 获取敏感行为表
  getSensitiveBehaviorList(page) {
    const { tableParams } = this.state;
    const { parent_operation_type_list, author_id, ...otherParams } = tableParams;
    this.setState({
      isLoading: true,
      openRowKeys: [],
    });

    exceed
      .forceFetch({
        api: 'organization.risk.sensitive_behavior',
        params: {
          org_id,
        },

        data: {
          parent_operation_type_list: parent_operation_type_list
            ? parent_operation_type_list.join(',')
            : null,
          author_id: author_id ? author_id.join(',') : null,
          ...otherParams,
          page,
          per_page: 10,
        },
      })
      .then((result) => {
        const { list } = result;
        const total = result.amount || 0;
        this.setState({
          tableData: list,
          isLoading: false,
          total,
          page,
        });
      });
  }

  // 获取敏感行为详情
  getSensitiveBehaviorDetailsById(parent_id, cb) {
    exceed
      .forceFetch({
        api: 'organization.risk.sensitive_behavior_detail',
        params: {
          org_id,
        },

        data: {
          parent_id,
        },
      })
      .then((result) => {
        // eslint-disable-next-line react/no-access-state-in-setstate
        const tableData = [...this.state.tableData];
        const details = result.list;
        tableData.find((item) => item.uid === parent_id).moreDetails = details;
        this.setState({
          tableData,
        });

        cb && cb(result);
      });
  }

  renderUser = (value) => {
    return (
      <Tooltip
        trigger={<div className="table-cell-one-line">{value}</div>}
        align="t"
        popupContainer={(trigger) => trigger.parentNode}
      >
        {value}
      </Tooltip>
    );
  };

  renderType = (value) => {
    // 空格隔开
    const types = value.includes(',') ? value.split(',') : [];
    const text =
      types
        .map((item) => {
          return ACTION_TYPES[item];
        })
        .join(', ') || '';
    return types.length ? text : ACTION_TYPES[value];
  };

  renderBehavior = (value, index, record) => {
    const strArr = record.merged_details.map((item) => {
      const { operation_type } = item;

      let str;
      switch (operation_type) {
        case 'FREQUENT_PULL': {
          const projectNames = item.project_names.join(', ');
          str = intl.get(
            {
              id: 'code-assets.sensitiveBehaviorMonitor.recordTable.PullTheCodeLibraryProjectnames',
              defaultMessage: '拉取代码库 [{projectNames}] 共 {itemTotalPull} 次',
            },
            { projectNames, itemTotalPull: item.total_pull_count },
          );
          break;
        }
        case 'SENSITIVE_DEL_REPO': {
          const projectNames = item.project_names.join(', ');
          str = intl.get(
            {
              id: 'code-assets.sensitiveBehaviorMonitor.recordTable.DeleteTheCodeLibraryProjectnames',
              defaultMessage: '删除代码库 [{projectNames}]',
            },
            { projectNames },
          );
          break;
        }
        case 'SENSITIVE_MOD_MEMBER': {
          const { current_access } = item;
          let role;
          if (PROJECT_ADMIN_ROLES.includes(current_access)) {
            role = intl.get({
              id: 'code-assets.sensitiveBehaviorMonitor.recordTable.Administrator',
              defaultMessage: '管理员',
            });
          } else if (PROJECT_DEVELOPER_ROLES.includes(current_access)) {
            role = intl.get({
              id: 'code-assets.sensitiveBehaviorMonitor.recordTable.Developers',
              defaultMessage: '开发者',
            });
          } else if (PROJECT_VIEW_ROLES.includes(current_access)) {
            role = intl.get({
              id: 'code-assets.sensitiveBehaviorMonitor.recordTable.Visitors',
              defaultMessage: '浏览者',
            });
          } else {
            role = '';
          }
          const entityNames = item.entity_names.join(', ');
          const projectName = item.target_project_name;
          str = role
            ? intl.get(
                {
                  id: 'code-assets.sensitiveBehaviorMonitor.recordTable.ChangeTheEntitynamesPermissionTo',
                  defaultMessage: '变更 [{entityNames}] 权限为库 [{projectName}] {role}',
                },
                { entityNames, projectName, role },
              )
            : intl.get(
                {
                  id: 'code-assets.sensitiveBehaviorMonitor.recordTable.RemoveProjectnameFromLibraryEntitynames',
                  defaultMessage: '从库 [{projectName}] 移除 [{entityNames}]',
                },
                { projectName, entityNames },
              );
          break;
        }
        case 'SENSITIVE_ORG_ADD_ADMIN':
        case 'SENSITIVE_ORG_ADD_OWNER':
        case 'SENSITIVE_ORG_DEL_ADMIN':
        case 'SENSITIVE_ORG_DEL_OWNER':
          str = `${BEHAVIORS[item.operation_type]} [${item.entity_names.join(', ')}]`;
          break;
        default:
          break;
      }

      return str;
    });
    const result = strArr.join(', ') || '';

    return (
      <Tooltip trigger={<div className="table-cell-one-line">{result}</div>} align="t">
        {result}
      </Tooltip>
    );
  };

  expandedRowRender = (record) => {
    const { tableData } = this.state;
    const rowData = tableData.find((item) => item.uid === record.uid);
    const details = rowData && rowData.moreDetails;

    if (!details) {
      return <ListLoading />;
    }

    const ipArr = [];
    details.forEach((item) => {
      const itemDetails = item.details || [];
      itemDetails.forEach((dtl) => {
        const txt = dtl.location
          ? intl.get(
              {
                id: 'code-assets.sensitiveBehaviorMonitor.recordTable.DtlipDtllocation',
                defaultMessage: '{dtlIp} 【{dtlLocation}】',
              },
              { dtlIp: dtl.ip, dtlLocation: dtl.location },
            )
          : `${dtl.ip} `;
        if (!ipArr.includes(txt)) {
          ipArr.push(txt);
        }
      });
    });

    return (
      <div className="behavior-details">
        {details.map((item, key) => (
          <div className="behavior-details-type">
            <div className="behavior-details-type-num">{key + 1}.</div>
            <div className="behavior-details-type-title">{BEHAVIORS[item.operation_type]}</div>
            <div className="behavior-details-type-body">
              {item.operation_type === 'FREQUENT_PULL' ? (
                this.renderBehaviorDetailForFrequentPull(item.details)
              ) : (
                <div>
                  {item.details.map((detail) => {
                    return this.renderBehaviorDetail(detail, item.operation_type);
                  })}
                </div>
              )}
            </div>
          </div>
        ))}

        <div className="behavior-details-footer">
          <Title align="t" trigger={<span className="ip">IP: {ipArr.join(' ')}</span>}>
            IP: {ipArr.join(' ')}
          </Title>
        </div>
      </div>
    );
  };

  renderBehaviorDetail = (detail, operation_type) => {
    let result = '';

    // 异常删库
    if (operation_type === 'SENSITIVE_DEL_REPO') {
      const { project_name, operation_time } = detail;

      result = (
        <div className="behavior-details-type-item">
          <div className="behavior-details-type-item-col behavior-details-type-item-col-2">
            {intl.get({
              id: 'code-assets.sensitiveBehaviorMonitor.recordTable.DeleteACodeBase',
              defaultMessage: '删除代码库 [',
            })}
            <span className="deleted-repo">{project_name}</span>]
          </div>
          <div className="behavior-details-type-item-col behavior-details-type-item-col-time">
            {utils.getBeautyTime(operation_time)}
          </div>
        </div>
      );
    }

    // 变更库成员
    if (operation_type === 'SENSITIVE_MOD_MEMBER') {
      const { current_access } = detail;
      let role;
      if (PROJECT_ADMIN_ROLES.includes(current_access)) {
        role = intl.get({
          id: 'code-assets.sensitiveBehaviorMonitor.recordTable.Administrator',
          defaultMessage: '管理员',
        });
      } else if (PROJECT_DEVELOPER_ROLES.includes(current_access)) {
        role = intl.get({
          id: 'code-assets.sensitiveBehaviorMonitor.recordTable.Developers',
          defaultMessage: '开发者',
        });
      } else if (PROJECT_VIEW_ROLES.includes(current_access)) {
        role = intl.get({
          id: 'code-assets.sensitiveBehaviorMonitor.recordTable.Visitors',
          defaultMessage: '浏览者',
        });
      } else {
        role = '';
      }

      result = (
        <div className="behavior-details-type-item">
          <div className="behavior-details-type-item-col behavior-details-type-item-col-2">
            {role ? (
              <span>
                {intl.get(
                  {
                    id: 'code-assets.sensitiveBehaviorMonitor.recordTable.ChangeTheDetailentitynamePermissionTo',
                    defaultMessage: '变更 {detailEntityName} 权限为库 [',
                  },
                  { detailEntityName: detail.entity_name },
                )}
                <a
                  href={`/${organization_id}/${detail.project_path}`}
                  target="_blank"
                  rel="noreferrer"
                >
                  {detail.project_name}
                </a>
                {`] ${role}`}
              </span>
            ) : (
              <span>
                {intl.get({
                  id: 'code-assets.sensitiveBehaviorMonitor.recordTable.SlaveDatabase',
                  defaultMessage: '从库 [',
                })}
                <a
                  href={`/${organization_id}/${detail.project_path}`}
                  target="_blank"
                  rel="noreferrer"
                >
                  {detail.project_name}
                </a>
                {intl.get(
                  {
                    id: 'code-assets.sensitiveBehaviorMonitor.recordTable.RemoveDetailentityname',
                    defaultMessage: '] 移除 {detailEntityName}',
                  },
                  { detailEntityName: detail.entity_name },
                )}
              </span>
            )}
          </div>
          <div className="behavior-details-type-item-col behavior-details-type-item-col-time">
            {utils.getBeautyTime(detail.operation_time)}
          </div>
        </div>
      );
    }

    // 变更企业管理员
    if (
      [
        'SENSITIVE_ORG_ADD_ADMIN',
        'SENSITIVE_ORG_ADD_OWNER',
        'SENSITIVE_ORG_DEL_ADMIN',
        'SENSITIVE_ORG_DEL_OWNER',
      ].includes(operation_type)
    ) {
      result = (
        <div className="behavior-details-type-item">
          <div className="behavior-details-type-item-col behavior-details-type-item-col-2">
            {`${BEHAVIORS[operation_type]} ${detail.entity_name || ''}`}
          </div>
          <div className="behavior-details-type-item-col behavior-details-type-item-col-time">
            {utils.getBeautyTime(detail.operation_time)}
          </div>
        </div>
      );
    }

    return result;
  };

  // 大量拉取比较特殊，不是直接map details，要将details根据库名聚类
  renderBehaviorDetailForFrequentPull = (details) => {
    const groupedDetails = groupBy(details, (detail) => detail.project_name);
    return (
      <div className="frequent-pull-list">
        {Object.keys(groupedDetails).map((key) => (
          <span className="frequent-pull-list-item">
            <a
              href={`/${organization_id}/${groupedDetails[key][0].project_path}`}
              target="_blank"
              rel="noreferrer"
            >
              {key}
            </a>
            <span style={{ marginLeft: 4 }}>
              ({groupedDetails[key].length}
              {intl.get({
                id: 'code-assets.sensitiveBehaviorMonitor.recordTable.Times',
                defaultMessage: '次)',
              })}
            </span>
          </span>
        ))}
      </div>
    );
  };

  onRowOpen = (openRowKeys, currentRowKey, expanded, record) => {
    this.setState({
      openRowKeys,
    });

    if (expanded) {
      this.getSensitiveBehaviorDetailsById(record.uid);
    }
  };

  // 加入白名单的ips
  getIps = (result) => {
    if (!result) {
      return '';
    }
    const arr = [];
    result.forEach((item) => {
      const itemDetails = item.details || [];
      itemDetails.forEach((dtl) => {
        const { ip } = dtl;
        if (!arr.includes(ip)) {
          arr.push(ip);
        }
      });
    });
    return arr.join();
  };

  onPageNoChange = (page) => {
    this.getSensitiveBehaviorList(page);
  };

  render() {
    const { tableData, isModalOpen, isLoading, total, page, openRowKeys, tableParams, modalData } =
      this.state;

    return (
      <div>
        <div className="record-header">
          <Filter tableParams={tableParams} updateTableParams={this.updateRecordParams} />
        </div>
        <div className="behavior-table">
          <YunxiaoTable
            hasBorder
            dataSource={tableData}
            expandedRowRender={this.expandedRowRender}
            onRowOpen={this.onRowOpen}
            openRowKeys={openRowKeys}
            loading={isLoading}
            // lock和自定义占位一起使用有问题
            emptyContent={
              <ListEmpty
                content={intl.get({
                  id: 'code-assets.sensitiveBehaviorMonitor.recordTable.NoData',
                  defaultMessage: '暂无数据',
                })}
                imgType="search"
                className="table-list-empty"
                size="small"
              />
            }
            expandedRowIndent={[0, 1]}
          >
            <YunxiaoTable.Column
              title={intl.get({
                id: 'code-assets.sensitiveBehaviorMonitor.recordTable.AbnormalBehavior',
                defaultMessage: '异常行为',
              })}
              dataIndex="id"
              className="behavior-col"
              cell={this.renderBehavior}
              width={280}
            />

            <YunxiaoTable.Column
              title={intl.get({
                id: 'code-assets.sensitiveBehaviorMonitor.recordTable.Type',
                defaultMessage: '类型',
              })}
              dataIndex="composite_operation_type"
              cell={this.renderType}
              width={170}
            />

            <YunxiaoTable.Column
              title={intl.get({
                id: 'code-assets.sensitiveBehaviorMonitor.recordTable.Operator',
                defaultMessage: '操作人',
              })}
              dataIndex="author_name"
              cell={this.renderUser}
            />
            <YunxiaoTable.Column
              title={intl.get({
                id: 'code-assets.sensitiveBehaviorMonitor.recordTable.NotificationTime',
                defaultMessage: '通知时间',
              })}
              className="time-col"
              dataIndex="window_end"
              cell={utils.getBeautyTime}
              width={170}
            />

            <YunxiaoTable.Column
              title={intl.get({
                id: 'code-assets.sensitiveBehaviorMonitor.recordTable.Operation',
                defaultMessage: '操作',
              })}
              className="action-col"
              dataIndex="actions"
              cell={(value, index, record) => {
                return (
                  <Button
                    type="primary"
                    onClick={() => {
                      this.getSensitiveBehaviorDetailsById(record.uid, (result) => {
                        const allowed_ip_list = this.getIps(result.list);
                        this.setState({
                          isModalOpen: true,
                          modalData: {
                            allowed_ip_list,
                            users: [record.user_dto] || [],
                            operation_types: record.composite_operation_type
                              ? record.composite_operation_type.split(',')
                              : [],
                          },
                        });
                      });
                    }}
                    text
                  >
                    {intl.get({
                      id: 'code-assets.sensitiveBehaviorMonitor.recordTable.AddToWhitelist',
                      defaultMessage: '加入白名单',
                    })}
                  </Button>
                );
              }}
              lock="right"
              width={100}
            />
          </YunxiaoTable>
          <Pagination onChange={this.onPageNoChange} current={page} total={total} noBorderTop />
        </div>
        {isModalOpen && (
          <RuleModal
            isModalOpen={isModalOpen}
            type="new"
            data={modalData}
            onClose={() => {
              this.setState({
                isModalOpen: false,
                modalData: {},
              });
            }}
          />
        )}
      </div>
    );
  }
}
